home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c-part1 / 2073 < prev    next >
Encoding:
Text File  |  1996-08-05  |  6.1 KB  |  232 lines

  1. Path: mail2news.demon.co.uk!genesis.demon.co.uk
  2. From: Lawrence Kirby <fred@genesis.demon.co.uk>
  3. Newsgroups: comp.lang.c
  4. Subject: Re: Problem with program
  5. Date: Thu, 18 Jan 96 21:23:48 GMT
  6. Organization: none
  7. Message-ID: <822000228snz@genesis.demon.co.uk>
  8. References: <4dkr5u$ro7@hasle.sn.no>
  9. Reply-To: fred@genesis.demon.co.uk
  10. X-NNTP-Posting-Host: genesis.demon.co.uk
  11. X-Newsreader: Demon Internet Simple News v1.27
  12. X-Mail2News-Path: genesis.demon.co.uk
  13.  
  14. In article <4dkr5u$ro7@hasle.sn.no> elvemo@sn.no "Rune Elvemo" writes:
  15.  
  16. >Anyone who can figure out what is wrong with this program?
  17. >
  18. >I tried to compile it, but my compiler wouldn't.....
  19. >
  20. >Ex: It said that the prototype needed a semicolon, but it
  21. >don't.........
  22. >
  23. >
  24. >
  25. >/* Loadfile.c - loads a txt file, and shows it 
  26. >**
  27. >**
  28. >*/
  29. >
  30. >#include <stdio.h>
  31.  
  32. Since you use calloc below you need to declare it e.g. by:
  33.  
  34. #include <stdlib.h>
  35.  
  36. >
  37. >struct Text
  38. >{
  39. >char *str;
  40. >struct Text *next;
  41. >}
  42.  
  43. The ; is needed here.
  44.  
  45. >enum BOOL { TRUE, FALSE };
  46. >
  47. >/* prototype */
  48. >void PText(struct Text *);
  49. >
  50. >
  51. >main(int argc, char *argv[])
  52.  
  53. If this had come straight after your struct Text declaration the compiler
  54. would have interpreted struct Text as the return type for main (and probably
  55. not issued a warning). It is therefore better to write this fiully as:
  56.  
  57. int main(int argc, char *argv[])
  58.  
  59. >{
  60. >BOOL done = FALSE;
  61.  
  62. In C this must be:
  63.  
  64. enum BOOL done = FALSE;
  65.  
  66. >FILE *txtfile;
  67. >struct Text *first, *tst;
  68. >
  69. >if (argc >1)
  70. >     {
  71. >     if (txtfile = fopen(argv[1], "r"))
  72.  
  73. Many compilers will generate a 'helpful' warning about this just in case
  74. you mean == rather than =. It is a normal convention to 'reassure' the
  75. compiler (and anybody else reading your code for that matter) to write it
  76. as
  77.  
  78.       if ((txtfile = fopen(argv[1], "r")))
  79.  
  80. or
  81.  
  82.       if ((txtfile = fopen(argv[1], "r")) != NULL)
  83.  
  84. >          {
  85. >          if(first = calloc(1, sizeof(struct Text)))
  86.  
  87. The idea of calloc is to allocate an object from the heap and also
  88. initialise it to all bits zero. The only types that can be safely
  89. initialised this way are integer ones. You have no guarantee from the
  90. C language that all bits zero corresponds to 0.0 or NULL for floating point
  91. and pointer types. If you don't need to initialise the object then use
  92. malloc.
  93.  
  94. >               {
  95. >               tst = first;
  96. >               if (fgetc(txtfile) != -1)
  97.  
  98. fgetc returns EOF on an end-of-file or error condition. The language
  99. guarantees that EOF is less than zero but it does not guarantee that
  100. it is -1. So make that:
  101.  
  102.                 if (fgetc(txtfile) != EOF)
  103.  
  104. >                    {
  105. >                    while (!done)
  106. >                         {
  107. >                         if (tst->str = calloc(256, sizeof(char)))
  108.  
  109. sizeof(char) is defined to be 1 by the C language although there's nothing
  110. particularly wrong with stating it explicitly. It looks like you don't
  111. need the initialisation here so could use malloc(256) instead.
  112.  
  113. >                              {
  114. >                              do
  115. >                                   {
  116. >                                   *tst->str = fgetc(txtfile);
  117. >                                   tst->str++;
  118. >                                   *tst->str = 0;
  119. >/* check if the last char was LineFeed or EOF  */
  120. >
  121. >                                   } while ((*(tst->str - 1) != -1) &&
  122. >(*(tst->str) != 10));
  123.            ^^ -1 ???
  124.  
  125. Linefeed (end-of-line) is '\n' in C. On many implementations it has the
  126. value 10 but the language doesn't guarantee that. Also you have no
  127. guarantee that a char can store the value of EOF (which is why fgetc
  128. returns an int). You may be looking for something like:
  129.  
  130.                                while ((ch = fgets(txtfile)) != EOF &&
  131.                                                                  ch != '\n')
  132.                                     *tst->str++ = ch;
  133.  
  134.                                *tst->str = '\0';
  135.  
  136. Where ch was previously defined as an int. But note that like your code
  137. this doesn't test of writing beyond the end of the allocated buffer which
  138. it really should do (left as an exercise! :-) )
  139.  
  140. >                              if (*tst->str == -1)
  141. >                                   done = TRUE;
  142.  
  143. EOF again.
  144.  
  145. >                              else
  146. >                                   {
  147. >                                   if (tst->next = calloc(1,
  148. >sizeof(struct Text)))
  149. >                                        {
  150. >                                        tst = tst->next;
  151. >
  152. >                                        }
  153. >                                   else
  154. >                                        {
  155. >                                        done = TRUE;
  156. >                                        printf("\n**!!Not enough
  157. >memory!!**\n");
  158. >                                        }
  159. >                                   }
  160. >                              }
  161. >                         }
  162. >                    tst->next = calloc(1, sizeof(struct Text));
  163. >                    
  164. >                    
  165. >                    PText(first);
  166. >                    }
  167. >               }
  168. >          else
  169. >               printf("\n**!!Not enough memory!!**\n");
  170. >          }
  171. >     }
  172.  
  173. Since main returns an int:
  174.  
  175.       return 0;
  176. >}
  177. >     
  178. >/* Print the text that we have got */
  179. >void PText(struct Text *txt)
  180. >{
  181. >BOOL done = FALSE;
  182.  
  183. enum BOOL done = FALSE;
  184.  
  185. >struct Text *jump;
  186. >
  187. >jump = txt;
  188. >
  189. >while(!done)
  190.  
  191. Done doesn't seem to be set TRUE anywhere.
  192.  
  193. >     {
  194. >     printf("%s", jump->str);
  195. >     
  196. >     while (*txt->next != 0)
  197.  
  198. You are trying to compare a structure against 0 which is illegal. You want
  199. to compare the pointer e.g.
  200.  
  201.       while (jump->next != NULL)
  202.  
  203. I assume you wanted to compare the link in the current element, not the
  204. first each time!
  205.  
  206. >          {
  207. >          jump = jump->next;
  208. >          
  209. >          printf("%s\n", jump);
  210.  
  211.            printf("%s\n", jump->str);
  212.  
  213. >          }
  214. >     }
  215. >}
  216.  
  217. You may prefer:
  218.  
  219. void PText(const struct Text *txt)
  220. {
  221.     const struct Text *jump;
  222.  
  223.     for (jump = txt; jump != NULL; jump = jump->next)
  224.         printf("%s\n", txt->str);
  225. }
  226.  
  227. -- 
  228. -----------------------------------------
  229. Lawrence Kirby | fred@genesis.demon.co.uk
  230. Wilts, England | 70734.126@compuserve.com
  231. -----------------------------------------
  232.